#pragma once

#include <Windows.h>
#include <process.h>

enum MsgType
{
	MSG_BodyInfo,
	MSG_SPRINGINFO,
	MSG_TOGGLESPRING,
	MSG_SPRINGACTIVE,
	MSG_NEWCIRCLE,
	MSG_MORECIRCLES,
	MSG_NEWAIRJET,
	MSG_STATS,
	MSG_UPD_ELASTICITY,
	MSG_UPD_FRICTION,
	MSG_UPD_PAUSE,
	MSG_UPD_GRAPHICSFREQ,
	MSG_UPD_NETWORK_FREQ,
	MSG_UPD_PHYSICS_FREQ
};

struct Header
{
	MsgType type;
	int		length;
};

struct Message
{
	Header	header;
	void*	data;
};

class Server;

class Connection
{
	public:
		Connection(Server* srv)	: m_server(srv), m_bTerminate(false), mConnected(true), bLocked(false) {} 
		~Connection() {}

		void			init(int port);
		void			start(unsigned int id, int port);
		void			waitForTermination();

		void			terminate() { m_bTerminate = true; }
		bool			isTerminated() const { return m_bTerminate; }

		void			startTimer();
		double			getDeltaTime();
		double			getTime();

		void			restart(int port);
		
		in_addr&		address();
		
	private:
		in_addr			mAddress;
		
		bool			mConnected;

		void			close();

		int				mPort;

		bool			bLocked;

		__int64			tmr_start;
		double			freq;	

		bool			updateClient();

		Server*			m_server;

		bool			receive(SOCKET socket, char* data, int size);

		unsigned int	m_Id;

		bool			m_bTerminate;

		int				sendData();
		int				receiveData();

		HANDLE			m_hSend;
		HANDLE			m_hReceive;

		SOCKET			m_socket;

		static unsigned __stdcall threadSend(void* param) {
			if (param)
				return ((Connection*)param)->sendData();
			return 1;
		}

		static unsigned __stdcall threadReceive(void* param) {
			if (param)
				return ((Connection*)param)->receiveData();
			return 1;
		}
};